/** The example provide a way of two communication between clients and server.
   The program acts like a simple chat room.

   It keep track of clients' names and their remote object so that this remote server
object can call the remote client object's public method to display other clients'
message.

*/

import java.util.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;

public class SimpleServer2Impl extends UnicastRemoteObject
			       implements MessageReceiver {

    Hashtable<String, MessageReceiver> clients = new Hashtable<String, MessageReceiver>(5);

    public SimpleServer2Impl() throws RemoteException {}

    public void write(String clientName, String msg ) {
	System.out.println(clientName + ": " + msg);

	try { 
	   // Broadcasting the message to each of all clients
	   Enumeration e = clients.elements();
	   MessageReceiver m ;
	   while ( e.hasMoreElements() ) {
		m = (MessageReceiver) e.nextElement();

		// call MessageReceiver's public method.
		m.showMessage( clientName + ": " + msg );
	   }
	} catch (RemoteException e) { e.printStackTrace() ; }
		
    }

    public int register( String name, MessageReceiver m) {
	System.out.println("Register() called!");

	if ( name != null && m != null ) {
		if ( clients.get(name) == null ) { 
			clients.put(name, m);
			System.out.println(name + " registered!");
			return MessageReceiver.REGISTRY_SUCCEED;
		} else {
			System.out.println(name + " already existed!");
		}
	} else {
		System.out.println("Registry failured");
	}
	return MessageReceiver.REGISTRY_FAIL;
    }

    public void showMessage(String msg) throws RemoteException {}

    // Remote server application: define a server object and bind remote 
    // server object with a unique name.
    public static void main(String args[] ) {
       try {

	SimpleServer2Impl svrObj = new SimpleServer2Impl();

	Naming.rebind( "//localhost:3942/" + MessageReceiver.serverName,  svrObj);

       } catch (Exception e) //for catching RemoteException and Misformed URL name.
	{ e.printStackTrace(); }
    }

}
